using System;
using System.Collections.Generic;
using System.Text;

namespace EntLibContrib.PolicyInjection
{
    /// <summary>
    /// A generic way to treat groups of objects as a key.
    /// </summary>
    public class Key
    {
        private EqualityType type;
        private object[] items;


        public Key(EqualityType type, params object[] items)
        {
            this.type = type;
            this.items = items;
        }

        public override int GetHashCode()
        {
            int hashCode = 0;

            foreach (object item in items)
            {
                if (item != null)
                {
                    hashCode ^= item.GetHashCode();
                }
            }

            return hashCode;
        }

        public override bool Equals(object obj)
        {
            Key other = obj as Key;

            if (other == null)
            {
                return false;
            }

            if (items.Length != other.items.Length)
            {
                return false;
            }

            for (int i = 0; i < items.Length; ++i)
            {
                if (!AreEqual(items[i], other.items[i]))
                {
                    return false;
                }
            }

            return true;
        }

        protected virtual bool AreEqual(object x, object y)
        {
            if (type == EqualityType.Equals)
            {
                return Equals(x, y);
            }
            else
            {
                return ReferenceEquals(x, y);
            }
        }
    }
}
